<?php

use app\service\config;
use Payment\Pay;
use Payment\PayType;
use Payment\Notify;

class PayService
{
    protected $config;
    protected $platform;
    protected $payment;
    protected $notify_url;
    protected $pay_type;

    public $method;

    public function __construct($payment, $platform = '', $notify_url = '')
    {
        $this->platform = $platform;
        $this->payment = $payment;
        $this->notify_url = $notify_url;

        $this->setPaymentConfig();
        $this->matchPayType();
    }

    private function setPaymentConfig()
    {
        $paymentConfig = config::get($this->payment);
        $supportPlatformList = ['H5', 'wxMiniProgram', 'wxOfficialAccount', 'App'];

        // 如果是支付，并且不是 复制地址的支付宝支付
        if (!in_array($this->platform, $supportPlatformList)) {
            throw new \Exception('暂不支持该支付方式');
        }

        $this->config = $paymentConfig;
        $this->config['notify_url'] = $this->notify_url;
    }

    private function matchPayType()
    {
        if ($this->payment == 'wechat') {
            switch ($this->platform) {
                case 'H5':
                    $this->pay_type = PayType::WX_H5;
                    break;
                case 'wxMiniProgram':
                    $this->pay_type = PayType::WX_Minipro;
                    break;
                case 'wxOfficialAccount':
                    $this->pay_type = PayType::WX_JSPAY;
                    break;
                case 'App':
                    $this->pay_type = PayType::WX_APP;
                    break;
                default:
                    break;
            }
        }
        if ($this->payment == 'alipay') {
            switch ($this->platform) {
                case 'H5':
                    $this->pay_type = PayType::ALI_H5;
                    break;
                case 'App':
                    $this->pay_type = PayType::ALI_APP;
                    break;
                default:
                    break;
            }
        }
    }

    public function create($orderData)
    {
        trace('wechat pay info:' . json_encode(['config' => $this->config, 'orderdata' => $orderData]));
        $pay = Pay::run($this->pay_type, $this->config, $orderData);
        return $pay;
    }

    // 企业付款
    public function transfer($payload)
    {
        $code = 0;
        $response = [];
        switch ($this->payment) {
            case 'wechat':
                $payload['amount'] = $payload['amount'] * 100;
                $response = Pay::wechat($this->config)->transfer($payload);
                if ($response['return_code'] === 'SUCCESS' && $response['result_code'] === 'SUCCESS') {
                    $code = 1;
                }
                break;
            case 'alipay':
                $response = Pay::alipay($this->config)->transfer($payload);
                if ($response['code'] === '10000' && $response['status'] === 'SUCCESS') {
                    $code = 1;
                }
                break;
        }

        return [$code, $response];
    }

    public function notify($class, $method, $ordersn = '')
    {
        switch ($this->payment) {
            case 'wechat':
                $notifyType = 'NotifyWx';
                break;
            case 'alipay':
                $notifyType = 'NotifyAli';
                break;
            default:
                break;
        }

        Log::out('notifyType:' . $notifyType, 'pay');
        Log::out("notifyClassMethod {$class}:{$method}", 'pay');

        Notify::run($notifyType ?? '', $this->config, [$class, $method]);
    }


    public function refund($refundData, $notify_url = '')
    {
        $this->config['notify_url'] = $notify_url;
        if ($this->payment == 'wechat') {
            $refund = PayType::WX_REFUND;
            $this->config['sslcert_path'] = APP_PATH . $this->config['cert_client'];
            $this->config['sslkey_path'] = APP_PATH . $this->config['cert_key'];
        } else {
            $refund = PayType::ALI_REFUND;
        }
        $result = Pay::run($refund, $this->config, $refundData);
        return $result;
    }


    public function notifyRefund($callback)
    {
        $pay = $this->getPay();
        try {
            $data = $pay->verify(null, true); // 是的，验签就这么简单！

            $result = $callback($data, $pay);

        } catch (\Exception $e) {
            // $e->getMessage();
        }
        return $result;
    }


    private function getPay()
    {
        switch ($this->payment) {
            case 'wechat':
                $pay = Pay::wechat($this->config);
                break;
            case 'alipay':
                $pay = Pay::alipay($this->config);
                break;
            default:
                throw new \Exception('支付方式不支持');
        }
        return $pay;
    }
}
